package com.easyj.admin.activiti.serviceimpl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.activiti.api.runtime.shared.security.SecurityManager;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.easyj.admin.activiti.service.ActTaskService;
import com.easyj.admin.activiti.service.TaskCommentService;
import com.easyj.admin.activiti.utils.ProcessUtils;
import com.easyj.admin.activiti.vo.TaskQO;
import com.easyj.admin.activiti.vo.TaskVO;
import com.easyj.admin.db.model.TaskComment;
import com.easyj.base.common.page.Page;
import com.easyj.base.security.service.SecurityUtil;
import com.easyj.base.cache.SysCacheUtil;

/**
 *  任务查询
 * @author hjf
 *
 */
@Service
public class ActTaskServiceImpl implements ActTaskService{
	
	 @Autowired
	 private TaskService taskService;
	 
	 @Autowired
	 private  SecurityManager securityManager;
	 
	 @Autowired
	 private RuntimeService runtimeService;
	 
	 @Autowired
	 private HistoryService  historyService;
	 
	 @Autowired
	 private TaskCommentService taskCommentService;
	 
	 @Autowired
	  private TaskRuntime taskRuntime;
	 
	 /**
	  * 待办任务
	  * taskRuntime.tasks() 查询条件过于简单，使用taskService查询
	  * @param filter
	  * @return
	  */
	 public Page<TaskVO> findRuntimeTasks(TaskQO filter) {
		 
		 TaskQuery query=taskService.createTaskQuery();
		 
		 if(StringUtils.isNotBlank(filter.getProcDefKey()))
	    		query.processDefinitionKey(filter.getProcDefKey().trim());
		 
		 if(StringUtils.isNotBlank(filter.getTaskName()))
	    		query.taskName(filter.getTaskName().trim());
		 
		 //查询本人任务
		 String authenticatedUserId = securityManager.getAuthenticatedUserId();
		 List<String> userGroups = securityManager.getAuthenticatedUserGroups();
		 query.or()
	                .taskCandidateOrAssigned(authenticatedUserId,userGroups)
	                //.taskOwner(authenticatedUserId) //会同时查询到抄送子任务\已经委托的任务
	                .endOr()
	                .orderByTaskCreateTime().asc();
	    
		 long taskcount =  query.count();
		 List<TaskVO> list=new ArrayList<TaskVO>(); 
	     if(taskcount>0l) {
		       List<Task> taskList=	query.listPage(filter.getPage().getOffset().intValue(), filter.getPage().getLimit());
		       Set<String> processInstanceIdIds = taskList.parallelStream().map(t -> t.getProcessInstanceId()).collect(Collectors.toSet());
		       List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list();
		       for(Task t:taskList) {
		    	    TaskVO v=new TaskVO();
	        		v.setName(t.getName());
	        		v.setTaskId(t.getId());
	        		v.setProcInstId(t.getProcessInstanceId());       		
	        		v.setTaskDefKey(t.getTaskDefinitionKey());
	        		v.setBusinessKey(t.getBusinessKey()); //相关实体ID
	        		v.setCreateTime(t.getCreateTime());
	        		v.setFormKey(t.getFormKey());
	        		v.setParentTaskId(t.getParentTaskId());
	        		v.setOwnerId(t.getOwner());
	        		
	        		//如果是委托任务
        			DelegationState delegationState = t.getDelegationState();
        			String dlstate=delegationState!=null?delegationState.toString():"";
        			if(dlstate.length()>0){
        				v.setName("(委托)"+t.getName());
        			}
	        		
	        		
	        		ProcessInstance inst=null;
	        		for(ProcessInstance p:processInstanceList) {
	        			if(p.getId().equals(v.getProcInstId())) {
	        				inst=p;
	        				break;
	        			}
	        		}
	        		if(inst!=null) {
	        			v.setProcName(inst.getName());
	        			v.setProcDefKey(inst.getProcessDefinitionKey());
	        			
	        			//发起者为申请者
	        			v.setApplyTime(inst.getStartTime());
	        			try {
	        			  v.setBusinessKey(inst.getBusinessKey());//--	
	        			  Long userId=Long.parseLong(inst.getStartUserId());
	        			  v.setApplicantId(userId);
	        			  v.setApplicant(SysCacheUtil.getOperatorName(userId));
	        			}catch(Exception ex) {
	        				
	        			}
	        		}                     
	        		list.add(v);
	        		
		       }
		       
		       
		     //抄送子任务处理.... 
		       for(TaskVO v:list) {
		    	   if(v.getParentTaskId()!=null &&v.getProcInstId()==null) {
		    		   HistoricTaskInstance t=historyService.createHistoricTaskInstanceQuery().taskId(v.getParentTaskId()).singleResult();
		    		   HistoricProcessInstance inst =historyService.createHistoricProcessInstanceQuery().processInstanceId(t.getProcessInstanceId()).singleResult();
		  	    	   //task key
		    		   if(ProcessUtils.NotifyFormKey.equals(v.getFormKey())) {
		    		     v.setTaskDefKey(ProcessUtils.NotifyTaskKey);
		    		   }
		    		 
		    		   if(inst!=null) {
		        			v.setProcName(inst.getName());
		        			v.setProcDefKey(inst.getProcessDefinitionKey());
		        			
		        			//发起者为申请者
		        			v.setApplyTime(inst.getStartTime());
		        			try {
		        			  v.setBusinessKey(inst.getBusinessKey());//--	
		        			  Long userId=Long.parseLong(inst.getStartUserId());
		        			  v.setApplicantId(userId);
		        			  v.setApplicant(SysCacheUtil.getOperatorName(userId));
		        			}catch(Exception ex) {
		        				
		        			}
		        		}  
		    	   }
		       }
		       
		       //ownerName
		       for(TaskVO v:list) {
		    	   if(StringUtils.isNotBlank(v.getOwnerId())){
		    		   try {
		    		      v.setOwnerName(SysCacheUtil.getOperatorName(Long.parseLong(v.getOwnerId())));
		    		   }catch(Exception pt) {
		    			   
		    		   }
		    	   }
		       }
		       
		       
	     }
	     
	     
	     Page<TaskVO> rtn=new Page<TaskVO>(list,taskcount,filter.getPage());
	     return rtn;
	 }
	 
	 /**
	  * 待办任务
	  * taskRuntime.tasks() 查询条件过于简单，使用taskService查询
	  * @param filter
	  * @return
	  */
	 public long getRuntimeTaskCount() {
		 
		 TaskQuery query=taskService.createTaskQuery();
		 
		 //查询本人任务
		 String authenticatedUserId = securityManager.getAuthenticatedUserId();
		 List<String> userGroups = securityManager.getAuthenticatedUserGroups();
		 query.or()
	                .taskCandidateOrAssigned(authenticatedUserId,userGroups)
	                //.taskOwner(authenticatedUserId) //会同时查询到抄送子任务\已经委托的任务
	                .endOr();
	    
		 long taskcount =  query.count();
		 
	     return taskcount;
	 }
	 
	 /**
	  * 历史任务查询
	  * @param filter
	  * @return
	  */
	 public Page<TaskVO> findHistoryTasks(TaskQO filter) {		 
	
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
                .finished() // 已完成
                .taskAssignee(SecurityUtil.getOperatorId().toString()) // 分配给自己
                .orderByHistoricTaskInstanceEndTime().desc(); // 审批时间倒序
       
        if(StringUtils.isNotBlank(filter.getProcDefKey()))
    		query.processDefinitionKey(filter.getProcDefKey().trim());
	 
	    if(StringUtils.isNotBlank(filter.getTaskName()))
    		query.taskName(filter.getTaskName().trim());
	    
	    // 执行查询
	    long taskcount =  query.count();
		List<TaskVO> list=new ArrayList<TaskVO>(); 
	    if(taskcount>0l) {
	    	 List<HistoricTaskInstance> tasks = query.listPage(filter.getPage().getOffset().intValue(), filter.getPage().getLimit());
	    	 Set<String> processInstanceIdIds = tasks.parallelStream().map(t -> t.getProcessInstanceId()).collect(Collectors.toSet());
	    	 List<HistoricProcessInstance> processInstanceList =historyService.createHistoricProcessInstanceQuery().processInstanceIds(processInstanceIdIds).list();
	    	 for(HistoricTaskInstance t :tasks) {
	        	TaskVO v=new TaskVO();
        		v.setName(t.getName());
        		v.setTaskId(t.getId());
        		v.setProcInstId(t.getProcessInstanceId());       		
        		v.setTaskDefKey(t.getTaskDefinitionKey());        		
        		v.setCreateTime(t.getCreateTime());
        		v.setEndTime(t.getEndTime());
        		v.setAssignee(t.getAssignee()); //operator ID
        		v.setFormKey(t.getFormKey());
        		v.setParentTaskId(t.getParentTaskId());
        		//taskComment
        		List<TaskComment> comments=taskCommentService.findByTaskId(t.getId());
        		if(comments!=null && comments.size()>0) {
        			v.setTaskComment(comments.get(0).getMessage());
        		}
        		
        		HistoricProcessInstance inst=null;
        		for(HistoricProcessInstance p:processInstanceList) {
        			if(p.getId().equals(v.getProcInstId())) {
        				inst=p;
        				break;
        			}
        		}
        		if(inst!=null) {
        			v.setProcName(inst.getName());
        			v.setProcDefKey(inst.getProcessDefinitionKey());
        			
        			//发起者为申请者
        			v.setApplyTime(inst.getStartTime());
        			try {
        			  Long userId=Long.parseLong(inst.getStartUserId());
        			  v.setApplicantId(userId);
        			  v.setApplicant(SysCacheUtil.getOperatorName(userId));
        			  v.setBusinessKey(inst.getBusinessKey()); //相关实体ID
        			}catch(Exception ex) {
        				
        			}
        		}                     
        		list.add(v);
	        		
	         }
	    	 
	    	//抄送子任务处理.... 
		       for(TaskVO v:list) {
		    	   if(v.getParentTaskId()!=null &&v.getProcInstId()==null) {
		    		   HistoricTaskInstance t=historyService.createHistoricTaskInstanceQuery().taskId(v.getParentTaskId()).singleResult();
		    		   HistoricProcessInstance inst =historyService.createHistoricProcessInstanceQuery().processInstanceId(t.getProcessInstanceId()).singleResult();
		  	    	   //task key
		    		   if(ProcessUtils.NotifyFormKey.equals(v.getFormKey())) {
		    		     v.setTaskDefKey(ProcessUtils.NotifyTaskKey);
		    		   }
		    		 
		    		   if(inst!=null) {
		        			v.setProcName(inst.getName());
		        			v.setProcDefKey(inst.getProcessDefinitionKey());
		        			
		        			//发起者为申请者
		        			v.setApplyTime(inst.getStartTime());
		        			try {
		        			  v.setBusinessKey(inst.getBusinessKey());//--	
		        			  Long userId=Long.parseLong(inst.getStartUserId());
		        			  v.setApplicantId(userId);
		        			  v.setApplicant(SysCacheUtil.getOperatorName(userId));
		        			}catch(Exception ex) {
		        				
		        			}
		        		}  
		    	   }
		       }
	    
	    }
        
	    Page<TaskVO> rtn=new Page<TaskVO>(list,taskcount,filter.getPage());
	     return rtn;
       
	 }
	 
	 
	 /**
	  * 历史任务查询
	  * @param filter
	  * @return
	  */
	 public long getHistoryTaskCount() {		 
	
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
                .finished() // 已完成
                .taskAssignee(SecurityUtil.getOperatorId().toString()); // 分配给自己
               
	    long taskcount =  query.count();
	    return taskcount;
       
	 }
	 
	 public void completeNotifyTask(String taskId) {
		 org.activiti.api.task.model.Task task=taskRuntime.task(taskId);
		 taskRuntime.complete(TaskPayloadBuilder.complete()
	                .withTaskId(task.getId())
	                .build());
	 
	 }		
	 
}
